package com.dataseek.iot.sys.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dataseek.iot.sys.entity.Menu;
import com.dataseek.iot.sys.entity.Role;
import com.dataseek.iot.sys.entity.RoleMenu;
import com.dataseek.iot.sys.entity.UserRole;
import com.dataseek.iot.sys.mapper.MenuMapper;
import com.dataseek.iot.sys.service.MenuService;
import com.dataseek.iot.sys.service.RoleMenuService;
import com.dataseek.iot.sys.service.UserRoleService;
import com.dataseek.iot.sys.utils.GetChildUtil;
import com.dataseek.iot.sys.vo.MenuVo;
import com.dataseek.iot.toolikit.common.enums.RspStatusEnum;
import com.dataseek.iot.toolkit.tenant.config.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @discription:
 * @author: Freya.Yan
 * @date: 2022/1/11
 */
@Service
@Slf4j
public class MenuServiceImpl extends ServiceImpl<MenuMapper,Menu> implements MenuService {
    @Autowired
    private MenuMapper MenuMapper;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public List<MenuVo> queryMenu(String menuName, String status) {
        QueryWrapper<Menu> qw = new QueryWrapper<>();
        if (menuName != null && !menuName.isEmpty()) {
            qw.like("menu_name", menuName);
        }
        if (status != null && !status.isEmpty()) {
            qw.eq("status", status);
        }
        qw.orderByAsc("order_num");
        List<Menu> list = MenuMapper.selectList(qw);
        List<MenuVo> rootlist=new ArrayList<>();
        //遍历所有数据，找到根节点菜单
        for (Menu menu:list) {
            if(menu.getParentId() ==null ||"".equals(menu.getParentId()) || "0".equals(menu.getParentId() )){
                MenuVo menuVo = new MenuVo();
                menuVo.setMenuId(menu.getMenuId());
                menuVo.setIsUniq(menu.getIsUniq());
                menuVo.setMenuName(menu.getMenuName());
                menuVo.setMenuType(menu.getMenuType());
                menuVo.setIcon(menu.getIcon());
                menuVo.setStatus(menu.getStatus());
                menuVo.setParentId(menu.getParentId());
                menuVo.setOrderNum(menu.getOrderNum());
                menuVo.setPath(menu.getPath());
                menuVo.setPerms(menu.getPerms());
                //找到根节点菜单的时候，寻找这个根节点菜单下的子节点菜单。
                GetChildUtil.findChilds(menuVo,list);
                //添加到根节点的列表中
                rootlist.add(menuVo);
            }
        }
        return rootlist;
    }

    @Override
    public Integer updateMenu(Menu Menu) {
        int resultCode = MenuMapper.updateById(Menu);
        return resultCode;
    }

    @Override
    public Integer insertMenu(Menu Menu) {
        String tenantCode = DynamicDataSourceContextHolder.getDataSourceKey();
        int resultCode = 0;
        String code = Menu.getPath();
        QueryWrapper<Menu> qw = new QueryWrapper<>();
        qw.eq("path", code);
        Integer count = MenuMapper.selectCount(qw);
        if (count ==0 ) {
            Menu.setTenantCode(tenantCode);
            resultCode = MenuMapper.insert(Menu);
        } else {
            resultCode = RspStatusEnum.FAIL.getCode();
        }
        return resultCode;
    }

    @Override
    public Integer deleteMenu(List<Integer> MenuIds){
        int resultCode = MenuMapper.deleteBatchIds(MenuIds);
        return resultCode;
    }

    @Override
    public List<Menu> queryAllMenuTree() {
        List<Menu> menuList = new ArrayList<>();
        List<Menu> menus = this.list();
        menuList = getRootMenus(menus);
        return menuList;
    }

    @Override
    public List<Menu> queryMenuTree(Long userId) {
        List<Menu> menuList = new ArrayList<>();
        //根据用户id查询用户拥有的角色
        QueryWrapper<UserRole> qw1 = new QueryWrapper();
        qw1.select("distinct role_id");
        qw1.eq("user_id",userId);
        List<UserRole> roleList = userRoleService.list(qw1);
        //查询该角色下的所有菜单项
        if(roleList!=null&&roleList.size()>0) {
            List<Long> roleIdList = new ArrayList<>();
            for(UserRole userRole:roleList){
                roleIdList.add(userRole.getRoleId());
            }
            QueryWrapper<RoleMenu> qw2 = new QueryWrapper();
            qw2.select("distinct menu_id");
            qw2.in("role_id", roleIdList);
            //根据角色查询所有菜单项id
            List<RoleMenu> allRoleMenulist = roleMenuService.list(qw2);
            if(allRoleMenulist!=null&&allRoleMenulist.size()>0){
                List<Long> menuIdList = new ArrayList<>();
                for(RoleMenu roleMenu:allRoleMenulist){
                    menuIdList.add(roleMenu.getMenuId());
                }
                QueryWrapper<Menu> qw3 = new QueryWrapper<>();
                qw3.in("menu_id", menuIdList);
                qw3.orderByAsc("order_num");
                List<Menu> allMenuList = this.list(qw3);
                List<Menu> treeMenuList = getRootMenus(allMenuList);
                menuList=treeMenuList;
            }
        }
        return menuList;
    }

    //获取根节点
    private List<Menu> getRootMenus(List<Menu> allMenuList){
        List<Menu> resultList = new ArrayList<>();
        for(Menu menu:allMenuList){
            //根节点
            if(menu.getParentId()==-1){
                resultList.add(getChildren(menu,allMenuList));
            }
        }
        return resultList;
    }

    //递归获取子节点
    private Menu getChildren(Menu menu,List<Menu> allMenuList){
        List<Menu> children = new ArrayList<>();
        for(Menu menuNode:allMenuList){
            if(menuNode.getParentId()==menu.getMenuId()){
                children.add(getChildren(menuNode,allMenuList));
            }
        }
        if(children!=null&&children.size()>0) {
            menu.setChildren(children);
        }
        return menu;
    }

}
